//
//  NewCloudReserveController.swift
//  EyeVisionForPatients
//
//  Created by PMC on 2020/2/27.
//  Copyright © 2020 tao Tao. All rights reserved.
//

import UIKit

class NewCloudReserveController: BaseViewController {
    
    private let doctorVm: DoctorDetailViewModel
    private var doctorRowVm = DoctorScheduleViewModel(model: DoctorSchedule())
    
    init(with vm: DoctorDetailViewModel) {
        doctorVm = vm
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        setupUI()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        setupNotification()
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        NotificationCenter.default.removeObserver(self)
    }
    
    private var payVm = PayViewModel(order: PayOrderModel())
    
    private var viewModel = PublishViewModel() {
        didSet {
            payBtn.isEnabled = viewModel.isEnabled
            tableView.reloadData()
        }
    }

    @IBOutlet private weak var tableView: UITableView! {
        didSet {
            tableView.showsVerticalScrollIndicator = false
            tableView.showsHorizontalScrollIndicator = false
            tableView.backgroundColor = .background
            tableView.tableFooterView = UIView()
            tableView.register(PublishHeaderViewCell.nibForCell(),
                               forCellReuseIdentifier: PublishHeaderViewCell.reuseIdentifier())
            tableView.register(PublishLabelViewCell.nibForCell(),
                               forCellReuseIdentifier: PublishLabelViewCell.reuseIdentifier())
            tableView.register(PublishTextViewCell.nibForCell(),
                               forCellReuseIdentifier: PublishTextViewCell.reuseIdentifier_0)
            tableView.register(PublishButtonViewCell.nibForCell(),
                               forCellReuseIdentifier: PublishButtonViewCell.reuseIdentifier())
            tableView.register(PublishTextViewCell.nibForCell(),
                               forCellReuseIdentifier: PublishTextViewCell.reuseIdentifier_1)
            tableView.register(PublishTextViewCell.nibForCell(),
                               forCellReuseIdentifier: PublishTextViewCell.reuseIdentifier_2)
            tableView.register(PublishImageViewCell.nibForCell(),
                               forCellReuseIdentifier: PublishImageViewCell.reuseIdentifier())
            tableView.register(NewSectionHeaderView.nibForCell(),
                               forHeaderFooterViewReuseIdentifier: NewSectionHeaderView.reuseIdentifier())
            
            let tap = UITapGestureRecognizer(target: self, action: #selector(endEditing))
            tap.cancelsTouchesInView = false
            tableView.addGestureRecognizer(tap)
        }
    }
    
    @IBOutlet private weak var payBtn: UIButton! {
        didSet {
            payBtn.eventInterval = 2.0
            payBtn.isEnabled = false
            payBtn.setBackgroundImage(UIImage(color: .mainColor), for: .normal)
            payBtn.setBackgroundImage(UIImage(color: .mainLight), for: .highlighted)
            payBtn.setBackgroundImage(UIImage(color: .mainLight), for: .disabled)
        }
    }
    
    private var isAgree: Bool = false
}

// MARK: - Action
extension NewCloudReserveController {
    @IBAction private func viewAgreementAction(_ sender: UIButton) {
        let agreementView = UINib.loadViewFrom(AgreementAlertView.self)
        agreementView.show(type: .informedLetter)
    }
    
    @IBAction private func agreeAction(_ sender: UIButton) {
        sender.isSelected.toggle()
        isAgree = sender.isSelected
    }
    
    @IBAction private func payAction(_ sender: UIButton) {
        if !isAgree {
            HUDTool.show(message: "确定知情同意书及平台免责声明")
            return
        }
        
        reserveDoctorNo()
    }
    
    @objc private func endEditing() {
        tableView.endEditing(true)
    }
    
    //预约号源
    private func reserveDoctorNo() {
        HUDTool.showActivity()
        PublishViewModel.reserveDoctorNumber(numberId: viewModel.scheduleId,
                                             patientId: viewModel.patientId,
                                             doctorId: doctorVm.doctorId,
                                             departmentId: doctorVm.departmentId,
                                             regDocId: viewModel.patientId)
        { (registrationId, errorMsg, code) in
            switch code {
            case .failure:
                HUDTool.hideActivity()
                HUDTool.showError(message: errorMsg)
            case .success:
                self.generateOrder()
            }
        }
    }
    
    //生成订单
    private func generateOrder() {
        DoctorReserveViewModel.generateCloudOrder(userId: UserDefaults.userId,
                                                  scheduleId: viewModel.scheduleId,
                                                  patientId: viewModel.patientId,
                                                  condition: viewModel.desc,
                                                  imgIdsStr: viewModel.imgIds.joined(separator: ","),
                                                  allergyHistory: viewModel.allergyHistory,
                                                  pastHistory: viewModel.pastHistory,
                                                  success: { model in
            let payVm = PayViewModel(order: model)
            self.payVm = payVm
            self.wechatSubmitOrder(payVm)
        }) { errorMsg in
            HUDTool.hideActivity()
            HUDTool.showError(message: errorMsg)
        }
    }
    
    /// 选择支付方式
    private func showSelectPayStyleView(_ model: WXPayResult) {
        let styleView = UINib.loadViewFrom(SelectPayStyleView.self)
        styleView.show()
        styleView.configure(cost: model.ownAmount, time: "30")
        styleView.handlerClosure = { style in
            switch style {
            case .wechat:
                self.wechatPay(model)
            }
        }
        styleView.cancelClosure = { [weak self] in
            self?.pushMyCloudOrderVc()
        }
    }
    
    /// 微信支付统一提交订单
    private func wechatSubmitOrder(_ payVm: PayViewModel) {
        WXApiRequestHandler.wxPaySubmitOrder(orderId: payVm.orderId,
                                             orderAmount: doctorRowVm.regFee,
                                             orderType: .cloud,
                                             success: { wxModel in
            HUDTool.hideActivity()
            switch wxModel.getType {
            case 1:
                self.showSelectPayStyleView(wxModel)
            case 4:
                HUDTool.show(message: "医保已全额支付")
                self.pushPayResultVc()
            default:
                break
            }
        }) { (errorMsg, code) in
            HUDTool.hideActivity()
            HUDTool.showError(message: errorMsg)
            self.pushMyCloudOrderVc()
        }
    }
    
    /// 微信支付
    private func wechatPay(_ model: WXPayResult) {
        if !WXApi.isWXAppInstalled() {
            HUDTool.show(message: "未安装微信")
            return
        }
        
        WXApiRequestHandler.generateWXPayOrder(model: model)
    }
    
    @objc private func wechatPaySuccess(_ noti: Notification) {
        HUDTool.showActivity()
        PayViewModel.queryOrderStatus(orderId: payVm.orderId) { (errorMsg) in
            HUDTool.hideActivity()
            if errorMsg != nil {
                HUDTool.show(message: "订单支付失败")
                self.pushMyCloudOrderVc()
            } else {
                self.pushPayResultVc()
            }
        }
    }
    
    @objc private func wechatPayFailure(_ noti: Notification) {
        HUDTool.show(message: "订单支付失败")
        pushMyCloudOrderVc()
    }
    
    private func pushPayResultVc() {
        let payResultVc = PayResultViewController(with: viewModel, orderType: .cloud)
        removeCurrentVcWhenPush(payResultVc)
    }
    
    private func pushMyCloudOrderVc() {
        let orderVc = MyInquiryController(with: 1, startIndex: 0)
        removeCurrentVcWhenPush(orderVc)
    }
}

extension NewCloudReserveController {
    private func setupUI() {
        title = "预约云门诊"
    }
    
    private func setupNotification() {
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(wechatPaySuccess(_:)),
                                               name: NotiName.wechatPaySuccess,
                                               object: nil)
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(wechatPayFailure(_:)),
                                               name: NotiName.wechatPayFailure,
                                               object: nil)
    }
}

extension NewCloudReserveController: UITableViewDataSource, UITableViewDelegate {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 6
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        switch section {
        case 0: return 3
        case 1: return 2
        case 3: return viewModel.isAllergyHistory ? 2 : 1
        default: return 1
        }
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        switch indexPath.section {
        case 0:
            return firstSectionCell(at: indexPath)
        case 1:
            return secondSectionCell(at: indexPath)
        case 2:
            return thirdSectionCell(at: indexPath)
        case 3:
            return fourthSectionCell(at: indexPath)
        case 4:
            return fifthSectionCell(at: indexPath)
        case 5:
            return sixthSectionCell(at: indexPath)
        default:
            return UITableViewCell()
        }
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        switch indexPath.section {
        case 0: return indexPath.row == 0 ? 176 : 44
        case 1: return 44
        case 2: return 150
        case 3: return indexPath.row == 0 ? 44 : 80
        case 4: return 100
        case 5: return 250
        default: return 0
        }
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        switch section {
        case 2, 4, 5:
            let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: NewSectionHeaderView.reuseIdentifier()) as? NewSectionHeaderView
            header?.configure(at: section, title: "届时请提前打开APP等候")
            return header
        default:
            return UIView()
        }
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        switch section {
        case 0:
            let footer = UINib.loadViewFrom(YSGPublishRuleView.self)
            footer.configure(with: .cloud)
            return footer
        default: return nil
        }
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        switch section {
        case 0: return 78
        default: return 0.001
        }
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        switch section {
        case 0: return 0.001
        case 2: return 56
        case 4, 5: return 36
        default: return 16
        }
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        switch indexPath.section {
        case 0: firstCellSelect(at: indexPath)
        case 1: secondCellSelect(at: indexPath)
        case 2, 3, 4:
            if viewModel.patientId.isEmpty {
                HUDTool.show(message: "请先选择就诊人")
            }
        default: break
        }
    }
}

// MARK: - init cell
extension NewCloudReserveController {
    private func firstSectionCell(at indexPath: IndexPath) -> UITableViewCell {
        if indexPath.row == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: PublishHeaderViewCell.reuseIdentifier(),
                                                                 for: indexPath) as! PublishHeaderViewCell
            cell.delegate = self
            cell.configure(with: doctorVm)
            return cell
        } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: PublishLabelViewCell.reuseIdentifier(),
                                                                 for: indexPath) as! PublishLabelViewCell
            cell.configure(for: indexPath, vm: viewModel)
            return cell
        }
    }
    
    private func secondSectionCell(at indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: PublishLabelViewCell.reuseIdentifier(),
                                                 for: indexPath) as! PublishLabelViewCell
        cell.configure(for: indexPath, vm: viewModel)
        return cell
    }
    
    private func thirdSectionCell(at indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: PublishTextViewCell.reuseIdentifier_0) as! PublishTextViewCell
        cell.configure(for: indexPath, vm: viewModel, delegate: self)
        return cell
    }
    
    private func fourthSectionCell(at indexPath: IndexPath) -> UITableViewCell {
        if indexPath.row == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: PublishButtonViewCell.reuseIdentifier(),
                                                     for: indexPath) as! PublishButtonViewCell
            cell.delegate = self
            cell.configure(with: viewModel)
            return cell
        } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: PublishTextViewCell.reuseIdentifier_1,
                                                     for: indexPath) as! PublishTextViewCell
            cell.configure(for: indexPath, vm: viewModel, delegate: self)
            return cell
        }
    }
    
    private func fifthSectionCell(at indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: PublishTextViewCell.reuseIdentifier_2,
                                                 for: indexPath) as! PublishTextViewCell
        cell.configure(for: indexPath, vm: viewModel, delegate: self)
        return cell
    }
    
    private func sixthSectionCell(at indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: PublishImageViewCell.reuseIdentifier(),
                                                 for: indexPath) as! PublishImageViewCell
        cell.configure(with: viewModel, delegate: self)
        return cell
    }
    
    // MARK: - cell select event
    private func firstCellSelect(at indexPath: IndexPath) {
        if indexPath.row == 2 {
            let schedulePicker = UINib.loadViewFrom(SchedulePickerView.self)
            schedulePicker.frame = mainWindow.bounds
            schedulePicker.show(vm: doctorVm)
            schedulePicker.selectedClosure = { [weak self] vm in
                guard let self = self else { return }
                self.doctorRowVm = vm
                self.viewModel.reserveTime = vm.scheduleTime
                self.viewModel.cost = ""
                self.viewModel.scheduleId = ""
                self.viewModel.scheduleTime = ""
            }
        }
    }
    
    private func secondCellSelect(at indexPath: IndexPath) {
        if indexPath.row == 0 {
            let familyVc = FamilyViewController()
            familyVc.delegate = self
            navigationController?.pushViewController(familyVc, animated: true)
        } else {
            if viewModel.reserveTime.isEmpty {
                HUDTool.show(message: "请先选择远程门诊日期")
                return
            }
            let datePicker = CloudReserveDateController(with: doctorVm, scheduleVm: doctorRowVm)
            datePicker.modalPresentationStyle = .custom
            datePicker.closeClosure = { [weak self] dateVm in
                guard let self = self else { return }
                self.viewModel.scheduleId = dateVm.scheduleId
                self.viewModel.scheduleTime = dateVm.scheduleTime
                
                self.getCloudNumberAmount(doctorId: self.doctorVm.doctorId, scheduleId: dateVm.scheduleId)
            }
            present(datePicker, animated: true) {
                datePicker.view.backgroundColor = UIColor.black.withAlphaComponent(0.36)
            }
        }
    }
}

extension NewCloudReserveController:
FamilyViewControllerDelegate,
PublishTextViewCellDelegate,
PublishImageViewCellDelegate,
PublishButtonViewCellDelegate,
PublishHeaderViewCellDelegate {
    func familyVc(_ vc: FamilyViewController, didSelected vm: FamilyRowViewModel) {
        viewModel.patientId = "\(vm.patientId)"
        viewModel.patientName = vm.name
    }
    
    func textViewCell(_ cell: PublishTextViewCell, didEndEdit vm: PublishViewModel) {
        viewModel = vm
    }
    
    func imageCell(didClickedPickerImage cell: PublishImageViewCell) {
        Utilities.pushLoginVc(self)
        showBottomAlert()
    }
    
    func imageCell(_ cell: PublishImageViewCell, didDeleteImage vm: PublishViewModel) {
        viewModel = vm
    }
    
    func buttonViewCell(_ cell: PublishButtonViewCell, didClickedButton vm: PublishViewModel) {
        viewModel = vm
    }
    
    func headerViewCell(didIntroduceAction cell: PublishHeaderViewCell) {
        pushDoctorDetail(with: doctorVm.doctorId)
    }
    
    private func pushDoctorDetail(with doctorId: String) {
        let detailVc = DoctorDetailController(with: doctorId)
        navigationController?.pushViewController(detailVc, animated: true)
    }
}

// MARK: - UIImagePickerControllerDelegate
extension NewCloudReserveController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    private func showBottomAlert() {
        let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)

        let cancel = UIAlertAction(title:"取消", style: .cancel, handler: nil)
        let takingPictures = UIAlertAction(title:"拍照", style: .default) {
            action in
            self.goCamera()
            
        }
        let localPhoto = UIAlertAction(title:"从手机相册选择", style: .default) {
            action in
            self.goImage()
            
        }
        alert.addAction(cancel)
        alert.addAction(takingPictures)
        alert.addAction(localPhoto)
        present(alert, animated:true, completion:nil)
        
    }
    
    private func goCamera() {
        if UIImagePickerController.isSourceTypeAvailable(.camera){
            let cameraPicker = UIImagePickerController()
            cameraPicker.delegate = self
//            cameraPicker.allowsEditing = true
            cameraPicker.sourceType = .camera
            //在需要的地方present出来
            self.present(cameraPicker, animated: true, completion: nil)
        } else {
            HUDTool.show(message: "相机权限未打开!")
        }
    }
    
    private func goImage() {
        let photoPicker =  UIImagePickerController()
        photoPicker.delegate = self
//        photoPicker.allowsEditing = true
        photoPicker.sourceType = .photoLibrary
        //在需要的地方present出来
        self.present(photoPicker, animated: true, completion: nil)
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            YSGImageUpload.upload(image: image, imageType: .medicalRecord) { code, model, error in
                switch code {
                case .success:
                    guard let model = model else {
                        HUDTool.showError(message: "图片添加失败")
                        return
                    }
                    self.viewModel.append(model)
                    self.tableView.reloadData()
                case .failure:
                    HUDTool.showError(message: error)
                }
            }
        }
        self.dismiss(animated: true, completion: nil)
    }
}

// MARK: - 网络请求
private extension NewCloudReserveController {
    /// 获取云门诊号源价格
    func getCloudNumberAmount(doctorId: String, scheduleId: String) {
        HUDTool.showActivity()
        DoctorReserveViewModel.getCloudNumberAmount(doctorId: doctorId, scheduleId: scheduleId) { (amount, errorMsg) in
            HUDTool.hideActivity()
            if errorMsg != nil {
                HUDTool.showError(message: errorMsg)
                return
            }
            
            self.viewModel.cost = amount
        }
    }
}
